/**
* All Rights Reserved , Copyright (C) 2022 , 青岛鼎信通讯股份有限公司
*
* MpmCommentsService
* 评论表
*
* 修改纪录
* 2022-05-07 版本：1.0 mengmeng 创建。
* @version 版本：1.0
* @author 作者：mengmeng
* 创建日期：2022-05-07
*/
package com.topscomm.mpm.service.impl;

import com.topscomm.basic.BasicEntity;
import com.topscomm.basic.exception.ServiceException;
import com.topscomm.cbo.pojo.CboMessageAppEntity;
import com.topscomm.cbo.pojo.CboMessageSysEntity;
import com.topscomm.cbo.pojo.CboUserEntity;
import com.topscomm.cbo.service.ICboMessageAppService;
import com.topscomm.cbo.service.ICboMessageSysService;
import com.topscomm.cbo.service.ICboUserService;
import com.topscomm.mis.pojo.MisDeptHeaderEntity;
import com.topscomm.mis.service.IMisDeptHeaderService;
import com.topscomm.mpm.MpmSystemConst;
import com.topscomm.mpm.pojo.*;
import com.topscomm.mpm.service.*;
import com.topscomm.pub.util.ConvertUtil;
import com.topscomm.pub.util.StringBufferProxy;
import com.topscomm.pub.util.StringUtil;
import com.topscomm.tap.TapEntity;
import com.topscomm.tap.common.ParameterCache;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;

import com.topscomm.mpm.service.impl.auto.MpmCommentsServiceAuto;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.stream.Collectors;

@Service(value = "mpmCommentsService")
@Scope(value = "singleton")
public class MpmCommentsService extends MpmCommentsServiceAuto implements IMpmCommentsService {
    @Autowired
    private IMpmProjectService mpmProjectService;
    @Autowired
    private IMpmProjectTaskService mpmProjectTaskService;
    @Autowired
    private IMisDeptHeaderService misDeptHeaderService;
    @Autowired
    private ICboMessageAppService cboMessageAppService;
    @Autowired
    private ICboMessageSysService cboMessageSysService;
    @Autowired
    private ICboUserService cboUserService;
    @Autowired
    private IMpmProjectMilepostService mpmProjectMilepostService;
    @Autowired
    private ICommentsPermissionRecordService commentsPermissionRecordService;

    @Override
    protected void beforeInsert(BasicEntity entity) throws ServiceException {
        CboUserEntity currentUser = this.getSessionUserBean().getUser();
        entity.setValue(MpmCommentsEntity.FieldUsercode, currentUser.getCode());
        entity.setValue(MpmCommentsEntity.FieldUsername, currentUser.getName());
        entity.setValue(MpmCommentsEntity.FieldUserid, currentUser.getId());
        entity.setValue(MpmCommentsEntity.FieldDocdate, new Date());
    }

    protected void afterInsert(BasicEntity entity) throws ServiceException {
        MpmCommentsEntity comment = (MpmCommentsEntity) entity;
        String sourceType = comment.getSourcetype();
        String sourceId = ConvertUtil.convertToString(comment.getSourceid());
        boolean taskFlag = sourceType.equals(MpmProjectTaskEntity.tableName);
        if (taskFlag) {
            // 任务 要给对应的省总、sponsor、owner、项目经理、里程碑及任务责任人、任务责任人
            MpmProjectTaskEntity projectTaskEntity = mpmProjectTaskService.queryById(sourceId);
            List<MpmProjectEntity> mpmProjectList = getMpmProjectByTask(projectTaskEntity.getProjectcode());
            if (CollectionUtils.isEmpty(mpmProjectList)) {
                throw new ServiceException("未查询到该任务所处项目！");
            }
            // 任务责任人
            List<String> userCode = getProjectUserList(mpmProjectList.get(0));
            userCode.add(projectTaskEntity.getResponsiblecode());
            // 里程碑及任务责任人
            StringBufferProxy sql = new StringBufferProxy();
            sql.appendLineSingle(" {0} = '{1}' and  {2} = {3}", MpmProjectMilepostEntity.FieldOperatecode, projectTaskEntity.getMilepostcode(), MpmProjectMilepostEntity.FieldEnabled, 1);
            List<MpmProjectMilepostEntity> projectMilepostEntityList = mpmProjectMilepostService.queryByWhere(sql.toString());
            if (!CollectionUtils.isEmpty(projectMilepostEntityList)) {
                userCode.add(projectMilepostEntityList.get(0).getResponsiblecode());
            }
            List<CboUserEntity> userList = cboUserService.queryByWhere(" code in (" + userCode.stream().map(item -> "'" + item + "'").collect(Collectors.joining(",")) + ")");
            sql.clear();
            String projectName = projectTaskEntity.getProjectname();
            projectName = projectName.endsWith("项目") ? projectName : (projectName + "项目");
            String taskName = projectTaskEntity.getTaskname();
            taskName = taskName.endsWith("任务") ? taskName : (taskName + "任务");
            sql.appendLineSingle("{0}{3}有新的留言，留言人员为：{1}[{2}]，请登录销售项目系统查阅。", projectName, getSessionUserBean().getUser().getName(), getSessionUserBean().getUser().getCode(), taskName);
            // 设置权限
            generatePermission(entity, userCode);
            // 发送消息
            insertMessageAppFromTask(userList, sql.toString(), comment.getId());


        }
        else {
            // 项目需要给省总、sponsor、owner、项目经理发送消息提醒
            MpmProjectEntity project = mpmProjectService.queryById(sourceId);
            List<String> userCode = getProjectUserList(project);

            List<CboUserEntity> userList = cboUserService.queryByWhere(" code in (" + userCode.stream().map(item -> "'" + item + "'").collect(Collectors.joining(",")) + ")");
            StringBufferProxy message = new StringBufferProxy();
            String projectName = project.getProjectname();
            projectName = projectName.endsWith("项目") ? projectName : (projectName + "项目");
            message.appendLineSingle("{0}有新的留言，留言人员为：{1}[{2}]，请登录销售项目系统查阅。", projectName, getSessionUserBean().getUser().getName(), getSessionUserBean().getUser().getCode());
            // 设置权限
            Map<String, Object> paraMap = new HashMap<>();
            paraMap.put("projectcode", project.getProjectcode());
            List<Map<String, Object>> mpmProjectTaskList = mpmProjectTaskService.queryTaskForSystem(paraMap);
            List<String> permissionUserCodeList = new ArrayList<>(userCode);
            if (!CollectionUtils.isEmpty(mpmProjectTaskList)) {
                permissionUserCodeList.addAll(mpmProjectTaskList.stream().map(map -> ConvertUtil.convertToString(map.get(MpmProjectTaskEntity.FieldResponsiblecode))).collect(Collectors.toList()));
                // 查询里程碑及任务责任人
                StringBufferProxy sql = new StringBufferProxy();
                sql.appendLineSingle(" {0} in ({1}) and  {2} = {3}", MpmProjectMilepostEntity.FieldOperatecode, mpmProjectTaskList.stream().map(item -> "'" +  ConvertUtil.convertToString(item.get(MpmProjectTaskEntity.FieldMilepostcode)) + "'").collect(Collectors.joining(",")), MpmProjectMilepostEntity.FieldEnabled, 1);
                List<MpmProjectMilepostEntity> projectMilepostEntityList = mpmProjectMilepostService.queryByWhere(sql.toString());
                if (!CollectionUtils.isEmpty(projectMilepostEntityList)) {
                    permissionUserCodeList.addAll(projectMilepostEntityList.stream().map(MpmProjectMilepostEntity::getResponsiblecode).collect(Collectors.toList()));
                }
            }
            generatePermission(entity, permissionUserCodeList);
            // 发送消息
            insertMessageAppFromTask(userList, message.toString(), comment.getId());
        }
    }

    /**
    * @Description:    获取项目的省总、sponsor、owner、项目经理人员列表
    * @Author:         mengmeng
    * @Date:           2022/5/10 16:01
    * @Version:        1.0
    */
    public List<String> getProjectUserList(MpmProjectEntity project) {
        List<String> userCode = new ArrayList<>();
        userCode.add(project.getSponsorcode());
        userCode.add(project.getOwnercode());
        userCode.add(project.getProjectmanagercode());
        MisDeptHeaderEntity misDeptHeaderEntity = queryCEO(project.getDeptcode());
        userCode.add(misDeptHeaderEntity.getUsercode());
        return userCode;
    }

    private void generatePermission(BasicEntity entity, List<String> userCode) {
        userCode.add(getSessionUserBean().getUser().getCode());
        // 获取额外的默认权限人员
        String value = ParameterCache.getValue(MpmSystemConst.MPM_COMMENT_ADDITIONAL_PERMISSION);
        if (!StringUtil.isEmpty(value)) {
            userCode.addAll(Arrays.stream(value.split(",")).collect(Collectors.toList()));
        }
        CommentsPermissionRecordEntity commentsPermissionRecordEntity = new CommentsPermissionRecordEntity();
        String userCodeStr = userCode.stream().distinct().collect(Collectors.joining(","));
        commentsPermissionRecordEntity.setAuthorizeusercodes(userCodeStr);
        commentsPermissionRecordEntity.setSourceid(ConvertUtil.convertToString(entity.getId()));
        commentsPermissionRecordEntity.setSourcetype(MpmCommentsEntity.tableName);
        commentsPermissionRecordEntity.setSourceusercodes(getSessionUserBean().getUser().getCode());
        commentsPermissionRecordEntity.setSourceusernames(getSessionUserBean().getUser().getName());
        commentsPermissionRecordService.insert(commentsPermissionRecordEntity);
    }

    private void insertMessageAppFromTask(List<CboUserEntity> userList, String content, long id) {
        if (CollectionUtils.isEmpty(userList)) {
            return;
        }
        // 获取额外的默认权限人员
        String value = ParameterCache.getValue(MpmSystemConst.MPM_COMMENT_ADDITIONAL_PERMISSION);
        if (!StringUtil.isEmpty(value)) {
            String extraUserCodeStr = Arrays.stream(value.split(",")).map(item -> "'" + item + "'").collect(Collectors.joining(","));
            userList.addAll(cboUserService.queryByWhere(" code in (" + extraUserCodeStr + ")"));
        }
        List<Map<String, Object>> cboMessageAppMapList = new ArrayList<>();
        List<BasicEntity> cboMessageSysEntityList = new ArrayList<>();
        userList = userList.stream().distinct().collect(Collectors.toList());
        for (CboUserEntity user : userList) {
            // MessageApp消息发送
            Map<String, Object> cboMessageAppMap = new HashMap<>();
            cboMessageAppMap.put(CboMessageAppEntity.FieldContent, content);
            cboMessageAppMap.put(CboMessageAppEntity.FieldSourcetype, MpmCommentsEntity.tableName);
            cboMessageAppMap.put(CboMessageAppEntity.FieldSourceid, id);
            cboMessageAppMap.put(CboMessageAppEntity.FieldReceiverid, user.getId());
            cboMessageAppMap.put("usercode", user.getCode());
            cboMessageAppMap.put(CboMessageAppEntity.FieldSendtype, 0);
//            cboMessageAppMap.put(CboMessageAppEntity.FieldExtendfield1, projectName + subjectStr);// 从task表改
            cboMessageAppMapList.add(cboMessageAppMap);
            // MessageSys消息发送
            CboMessageSysEntity cboMessageSysEntity = new CboMessageSysEntity();
            cboMessageSysEntity.setContent(content);
            cboMessageSysEntity.setSourcetype(MpmCommentsEntity.tableName);
            cboMessageSysEntity.setSourceid(id);
            cboMessageSysEntity.setReceivercode(user.getCode());
            cboMessageSysEntity.setReceivername(user.getName());
            cboMessageSysEntity.setSubject("销售项目留言提醒");
            cboMessageSysEntityList.add(cboMessageSysEntity);
        }
        // 每50条数据插一次，防止oa hessian超时
        int baseRemindTaskEntityAppRemindListSize = userList.size();
        int lastIndex = 0;
        for (int i = 1; i <= baseRemindTaskEntityAppRemindListSize; i++) {
            if (i % 50 == 0 || i == (baseRemindTaskEntityAppRemindListSize)) {
                try {
                    this.cboMessageAppService.insertList(cboMessageAppMapList.subList(lastIndex, i));
                    this.cboMessageSysService.insertBatch(cboMessageSysEntityList.subList(lastIndex, i));
                } catch (Exception e) {
                }
                lastIndex = i;
            }
        }
    }

    @Override
    public List<Map<String, Object>> queryBySourceTypeAndSourceId(String sourceType, String sourceId, Map<String, Object> extraParam) {
        if (StringUtil.isEmpty(sourceType) || StringUtil.isEmpty(sourceId)) {
            return new ArrayList<>();
        }
        List<Map<String, Object>> result = new ArrayList<>();
        List<MpmCommentsEntity> commentList = queryBySourceTypeAndSourceIdList(sourceType, Collections.singletonList(sourceId), extraParam);
        boolean taskFlag = sourceType.equals(MpmProjectTaskEntity.tableName);
        MpmProjectEntity projectEntity;
        if (taskFlag) {
            MpmProjectTaskEntity taskEntity = mpmProjectTaskService.queryById(sourceId);
            String projectCode = taskEntity.getProjectcode();
            List<MpmProjectEntity> mpmProjectList = getMpmProjectByTask(projectCode);
            if (CollectionUtils.isEmpty(mpmProjectList)) {
                throw new ServiceException("未查询到该任务所处项目！");
            }
            projectEntity = mpmProjectList.get(0);
        }
        else {
            projectEntity = mpmProjectService.queryById(sourceId);
        }
        MisDeptHeaderEntity misDeptHeaderEntity = queryCEO(projectEntity.getDeptcode());
        if (!CollectionUtils.isEmpty(commentList)) {
            Map<String, Object> temp = new HashMap<>();
            temp.put("type", commentList.get(0).getTarget());
            temp.put("list", commentList);
            temp.put("active", !taskFlag);
            temp.put("ceo", misDeptHeaderEntity.getUsername());
            temp.put("ceoCode", misDeptHeaderEntity.getUsercode());
            temp.put("manager", projectEntity.getProjectmanager());
            temp.put("managerCode", projectEntity.getProjectmanagercode());
            temp.put("id", commentList.get(0).getId());
            temp.put("sourceType", sourceType);
            result.add(temp);
        }
        // 如果是项目的评论需要查找任务的评论,如果查询的是任务的评论可以直接返回
        if (taskFlag) {
            return result;
        }
        String projectCode = projectEntity.getProjectcode();
        Map<String, Object> paraMap = new HashMap<>();
        paraMap.put("projectcode", projectCode);
        List<Map<String, Object>> mpmProjectTaskList = mpmProjectTaskService.queryTaskForSystem(paraMap);
        // 任务为空，直接返回
        if (CollectionUtils.isEmpty(mpmProjectTaskList)) {
            return result;
        }
        List<String> sourceIdList = new ArrayList<>();
        sourceIdList.add(sourceId);
        for (Map<String, Object> mpmProjectTaskMap : mpmProjectTaskList) {
            sourceIdList.add(ConvertUtil.convertToString(mpmProjectTaskMap.get(MpmProjectTaskEntity.FieldId)));
        }
        List<MpmCommentsEntity> taskCommentList = queryBySourceTypeAndSourceIdList(MpmProjectTaskEntity.tableName, sourceIdList, extraParam);
        // 任务的评论为空， 直接返回
        if (CollectionUtils.isEmpty(taskCommentList)) {
            return result;
        }
        Map<String, List<MpmCommentsEntity>> targetMap = taskCommentList.stream().collect(Collectors.groupingBy(MpmCommentsEntity::getTarget));
        Map<String, Object> tempMap;
        for (Map.Entry<String, List<MpmCommentsEntity>> entry : targetMap.entrySet()) {
            tempMap = new HashMap<>();
            tempMap.put("type", entry.getKey());
            tempMap.put("list", listSortBySortCode(entry.getValue(), MpmCommentsEntity.FieldDocdate, MpmSystemConst.SortOrderTypeEnum.DESC));
            tempMap.put("active", false);
            tempMap.put("id", taskCommentList.get(0).getId());
            tempMap.put("ceo", misDeptHeaderEntity.getUsername());
            tempMap.put("ceoCode", misDeptHeaderEntity.getUsercode());
            tempMap.put("manager", projectEntity.getProjectmanager());
            tempMap.put("managerCode", projectEntity.getProjectmanagercode());
            tempMap.put("sourceType", MpmProjectTaskEntity.tableName);
            result.add(tempMap);

        }
        return result;
    }

    public List<MpmProjectEntity> getMpmProjectByTask(String projectCode) {
        StringBufferProxy sql = new StringBufferProxy();
        sql.appendLineSingle(" {0} = '{1}'", MpmProjectEntity.FieldProjectcode, projectCode);
        return mpmProjectService.queryByWhere(sql.toString());
    }

    /**
     * @Description:    list根据sortCode 进行 sidx 排序
     * @Param		    需要排序的list
     * @Author:         mengmeng
     * @Version:        1.0
     */
    private List<MpmCommentsEntity> listSortBySortCode(List<MpmCommentsEntity> list, String sortCode, String sidx) {
        if (org.apache.commons.collections.CollectionUtils.isNotEmpty(list)) {
            Collections.sort(list, new Comparator<MpmCommentsEntity>() {
                @Override
                public int compare(MpmCommentsEntity o1, MpmCommentsEntity o2) {
                    Date sortCodeO1 = ConvertUtil.convertToDate(o1.getValue(sortCode));
                    Date sortCodeO2 = ConvertUtil.convertToDate(o2.getValue(sortCode));
                    if (MpmSystemConst.SortOrderTypeEnum.DESC.equals(sidx)) {
                        return sortCodeO2.compareTo(sortCodeO1);
                    }
                    return sortCodeO1.compareTo(sortCodeO2);
                }
            });
        }
        return list;
    }

    private List<MpmCommentsEntity> queryBySourceTypeAndSourceIdList(String sourceType, List<String> sourceIdList, Map<String, Object> extraParam) {
        Map<String, Object> paraMap = null == extraParam ? new HashMap<>() : extraParam;
        paraMap.put("sourceType", sourceType);
        paraMap.put("sourceIdList", sourceIdList);
        paraMap.put("permissionUserCode", this.getSessionUserBean().getUser().getCode());
        return query(paraMap, "selectBySourceTypeAndSourceId");
    }

    public MisDeptHeaderEntity queryCEO(String deptCode) {
        StringBufferProxy sql = new StringBufferProxy();
        if (deptCode.contains("_")) {
            sql.appendSingle("deptcode ='{0}' and category = 'CEO'", deptCode.substring(0, deptCode.indexOf('_') + 5));
            return misDeptHeaderService.queryByWhere(sql.toString()).get(0);
        } else {
            sql.appendSingle("deptcode ='{0}' and category = 'CEO'", deptCode.substring(0, 4));
            return misDeptHeaderService.queryByWhere(sql.toString()).get(0);
        }
    }
}
